package com.okami;

import org.redisson.spring.starter.RedissonAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.task.TaskExecutorBuilder;
import org.springframework.context.annotation.*;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author 谭景玉
 */
@SpringBootApplication(exclude = {RabbitAutoConfiguration.class, RedissonAutoConfiguration.class, RedisAutoConfiguration.class})
//@EnableAspectJAutoProxy
public class DemoApplication {
    private static Integer cpuNums = Runtime.getRuntime().availableProcessors();

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    /**
     *  jdk dog李写的线程池.
     *  一开始池子里没有线程对象,有任务来的时候进行创建,保证常存活的数量为corePoolSize.
     *  执行任务分三步走:
     *  1.判断活动线程是否小于设定的corePoolSize,要是小于,就创建新线程放进池子里.
     *  2.要是不满足1,就判断队列能否塞下,当然了,同时也需要再次判断1,因为可能判断2的时候1成立了.
     *  3.要是1和2都不满足,则创建corePoolSize以外的线程,不超过maximunPoolSize.
     *  int cpuNums = Runtime.getRuntime().availableProcessors();
     */
//    @Bean
    public ThreadPoolExecutor threadPoolExecutor() {
        return new ThreadPoolExecutor(PoolEnum.corePoolSize.num, PoolEnum.maximumPoolSize.num, 100L ,TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50));
    }

    /**
     *  spring的线程池实现，装饰了jdk的线程池，装饰者模式
     *  在 {@link TaskExecutionAutoConfiguration} 配置类中，springboot自己注册了一个此线程池
     *  int cpuNums = Runtime.getRuntime().availableProcessors();
     */
//    @Bean
    public ThreadPoolTaskExecutor threadPoolTaskExecutor(TaskExecutorBuilder builder) {
        return builder
                .queueCapacity(500)
                .corePoolSize(2)
                .maxPoolSize(cpuNums +1)
                .threadNamePrefix("sanjicaigou-")
                .build();
    }

    public enum PoolEnum {
        corePoolSize(2),
        maximumPoolSize(5);

        private final Integer num;

        PoolEnum(int num) {
            this.num = num;
        }

        public Integer getNum() {
            return this.num;
        }
    }

}

